﻿
package projects.flashUpload {
	import extremefx.IDisposable;
	import extremefx.anim.Tween;
	import extremefx.drawing.SlicedBitmap;
	import extremefx.events.EventArgs;
	import extremefx.events.Events;
	import extremefx.events.ProgressEventArgs;

	import flash.display.DisplayObjectContainer;
	import flash.display.MovieClip;
	import flash.display.SimpleButton;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	import flash.text.TextField;

	/**
	 * @author Marcelo Volmaro
	 */
	public class Item implements IDisposable {
		public const OnRemove:Events = Events.create(this);
		
		public static const QEUED:uint = 1;
		public static const UPLOADING:uint = 2;
		public static const DONE:uint = 3;
		public static const ERROR:uint = 4;
		
		private var _item:MovieClip;
		/** items in movieclip */
		private var _name:TextField;
		private var _perc:TextField;
		private var _base:MovieClip;
		private var _remove:SimpleButton;
		
		private var _barBack:SlicedBitmap;
		private var _barTop:SlicedBitmap;
		private var _w:uint;
		
		private var _percent:ProgressEventArgs = new ProgressEventArgs(0, 0);
		private var _status:uint = QEUED;
		private var _upload:Upload;
		private var _disposed:Boolean;
		private var _indicator:MovieClip;

		public function Item(pUpload:Upload, pDo:DisplayObjectContainer) {
			_upload = pUpload;
			_item = new Item_mc();
			
			pDo.addChild(_item);
			
			_name = _item.name_txt;
			_perc = _item.perc_txt;
			_base = _item.base_mc;
			_indicator = _item.i_mc;
			
			_remove = _item.remove_btn;

			_name.text = pUpload.name;
			_remove.addEventListener(MouseEvent.CLICK, _doRemove, false, 0, true);
			
			Events.add(pUpload.OnStart, _onStart);
			Events.add(pUpload.OnProgress, _onProgress);
			Events.add(pUpload.OnComplete, _onCompleted);
			Events.add(pUpload.OnError, _onError);
			width = 0;
		}
		
		public function get upload():Upload {
			return _upload;
		}
		
		public function set x(pN:int):void {
			_item.x = pN;
		}
		
		public function get x():int {
			return _item.x;
		}
		
		public function set y(pN:int):void {
			_item.y = pN;
		}
		
		public function get y():int {
			return _item.y;
		}
		
		public function set width(pW:uint):void {
			_w = pW;
			_item.visible = pW != 0;
			if (pW == 0) return;

			_base.width = pW;
			_remove.x = pW - 32;
			_indicator.x = pW - 24;
			status = _status;
			
			_onProgress(_percent);
		}
		
		public function get width():uint {
			return _w;			
		}
		
		public function get height():uint {
			return _item.height;
		}
		
		public function remove(pDelay:uint):void {
			var t:Tween = Tween.animate(_item, 0.3);
			t.delay = pDelay;
			t.setProperty("alpha", 0);
			t.onComplete.add(_removeFromList);
		}
		
		public function set status(pStatus:uint):void {
			_item.gotoAndStop(pStatus);
			_base.gotoAndStop(pStatus);
			_name.width = (pStatus == ERROR || pStatus == QEUED) ? (_w - _name.x - 8) : int ((_w * 40 / 100) - 28);
			_remove.visible = pStatus == QEUED;
			_perc.visible = _indicator.visible = pStatus == UPLOADING;
			_status = pStatus;
			
			if (pStatus == UPLOADING){
				if (!_barBack) _setBarSize(_w, 0);
					
			} else {
				_setBarSize(0, 0);
			}
		}
		
		public function get status():uint {
			return _status;
		}
		
		private function _onProgress(pEventArgs:ProgressEventArgs):void {
			_percent = pEventArgs;
			_setBarSize(_w, pEventArgs.percent);
		}
		
		private function _setBarSize(pSize:uint, pPercent:Number):void {
			if (pSize == 0 || pPercent < 0 || _status != UPLOADING){
				_removeBar();
				
			} else {
				pSize -= 2;
				
				if (!_barBack){
					_barBack = new SlicedBitmap(
						new BarNormal(100, 14),
						false,
						false,
						new Rectangle(13, 1, 74, 12)
					);
					
					_item.addChild(_barBack);
					_barBack.y = 10;
				}
				
				if (!_barTop){
					_barTop = new SlicedBitmap(
						new BarComplete(96, 10),
						false,
						false,
						new Rectangle(11, 1, 74, 8)
					);
					
					_item.addChild(_barTop);
					_barTop.y = 12;
				}
				
				_item.addChild(_perc);
				
				_perc.x = _barBack.x = int (_name.width + 36);// (24 + 8)
				var percWidth:int = pSize - _barBack.x - 24;
				_barBack.setSize(percWidth, _barBack.height);
				_perc.width = percWidth;
				
				_perc.text = int(pPercent * 100) + "%";
				
				//pPercent = Math.pow((pPercent + (1 - pPercent) / 2), 8);
				
				_barTop.setSize((percWidth - 4) * pPercent, _barTop.height);//4 = adjustment
				_barTop.x = _barBack.x + 2;//adjustment
			}
		}
		
		private function _removeBar():void {
			if (_barBack) {
				_barBack.dispose();
				_barBack = null;
			}
			
			if (_barTop) {
				_barTop.dispose();
				_barTop = null;
			}
		}
	
		private function _removeFromList(pSender:Tween, pArgs:EventArgs):void {
			_removeBar();
			Events.fire(OnRemove);
		}
		
		private function _onCompleted(pEventArgs:EventArgs):void {
			if (status != ERROR){
				status = DONE;
				remove(.5);
			}
		}
		
		private function _onError(pEventArgs:EventArgs):void {
			status = ERROR;
			_name.text = _upload.lastError;
			remove(5);
		}
		
		private function _doRemove(event:MouseEvent):void {
			remove(0);
		}

		private function _onStart(pEventArgs:EventArgs):void {
			status = UPLOADING;
		}
		
		public function dispose():void {
			if (_disposed) return;
			_disposed = true;
			_upload.dispose();
			
			Events.removeAll(this);
			_remove.removeEventListener(MouseEvent.CLICK, _doRemove);
			_removeBar();
			_item.parent.removeChild(_item);
		}
	}
}
